package cn.bigfire.wedesk.util;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import lombok.SneakyThrows;
import org.junit.Test;

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MyRLE {
    private static ByteArrayOutputStream compressedData = new ByteArrayOutputStream(1024 * 1024 * 2);

    static HashMap<Integer, Integer> colorTable = new HashMap<>();

    static int currRgb = 0;
    public static byte[] compress(int[] bitmap, int from, int to){
        compressedData.reset();
        long start = System.currentTimeMillis();
        //建立颜色表
        for (int bit : bitmap) {
            if (bit != 0) {
                int color = color(bit);
                colorTable.put(color, colorTable.getOrDefault(color, 0) + 1);
            }
        }
        System.out.println("循环耗时:" + (System.currentTimeMillis() - start));
//        System.out.println(colorTable.size());
        System.out.println(JSON.toJSONString(colorTable));
        int count = 0;
        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
        for (int i = from; i < to; i++) {
            int color = bitmap[i];
            if (currRgb == color) {
                count++;
            } else {
                int num = count + 1;
//                compressedData.write(num);
                byte red = (byte) ((color >> 16) & 0xff);
                byte green = (byte) ((color >> 8) & 0xff);
                byte blue = (byte) ((color) & 0xff);
//                compressedData.write(red);
//                compressedData.write(green);
//                compressedData.write(blue);
                byteBuf.writeByte(num);
                byteBuf.writeByte(red);
                byteBuf.writeByte(green);
                byteBuf.writeByte(blue);
                count = 0;
            }
        }
        long cha = System.currentTimeMillis() - start;

//        byte[] byteArray = compressedData.toByteArray();

        byte[] byteArray = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(byteArray);

        System.out.println("耗时:" + cha + ",大小:" + ByteUtil.size(byteArray.length));
        return byteArray;
    }

    public static int color(int bit){
        int color = bit & 0xffffff;
        // 灰色RGB不减位
        if ((((color >> 16) & 0xff) ^ ((color >> 8) & 0xff)) == (color & 0xff)) return color;
        //减少位
        return color & 0xf0f0f0;
    }


    public static void main(String[] args) throws Exception {
        testEncode();
    }


    public static void testEncode() throws Exception {
        BufferedImage before = ImageIO.read(ResourceUtil.getResource("test1.bmp").openStream());
        BufferedImage curr = ImageIO.read(ResourceUtil.getResource("test1.png").openStream());
        int width = curr.getWidth();
        int height = curr.getHeight();
        int[] currRGB = curr.getRGB(0, 0, width, height, null, 0, width);
//        System.out.println("bitmap长度:" + currRGB.length);
//        System.out.println("总像素:" + width * height);

        int[] bitmap = new int[currRGB.length];
        int changedColors = 0, start = -1, end = bitmap.length;
        if (before != null) {
            int[] beforeRGB = before.getRGB(0, 0, width, height, null, 0, width);
            for (int i = 0; i < bitmap.length; i++) {
                if (beforeRGB[i] == currRGB[i]) {
                    bitmap[i] = 0;
                } else {
                    if (start == -1) start = i;
                    else end = i;
                    changedColors += 1;
                    bitmap[i] = currRGB[i];
                }
            }
        } else bitmap = currRGB;

        if (before != null && changedColors == 0) return;
        // Log.debug("Changed colors: " + changedColors);

        // 2. 压缩
        System.out.println("start:"+start);
        System.out.println("end:"+end);
        byte[] compressedData = compress(bitmap, start, end);
//        for (byte b : compressedData) {
//            System.out.print(b + ",");
//        }
//        System.out.println();


        ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
        ImageIO.write(curr, "png", baos1);
        byte[] bytes1 = baos1.toByteArray();
        System.out.println("原来数据:" + bytes1.length + ",压缩数据:" + compressedData.length + ",压缩比:" + compressedData.length * 100 / bytes1.length);
    }

    @Test
    @SneakyThrows
    public void testColor() {
        Color start = new Color(0, 0, 0);
//        Color start = new Color(255, 255, 255);
//        Color start = new Color(254, 254, 254);
//        Color end = new Color(255, 255, 255);
//        System.out.println(start.getRed());
//        System.out.println(start.getGreen());
//        System.out.println(start.getBlue());
        int rgb = start.getRGB();

        int red = (rgb >> 16) & 0xff;
        int green = (rgb >> 8) & 0xff;
        int blue = rgb & 0xff;
//        System.out.println(red);
//        System.out.println(green);
//        System.out.println(blue);

        compressedData.reset();
        compressedData.write(rgb);
        for (byte b : compressedData.toByteArray()) {
            System.out.print(b + ",");
        }
        System.out.println();


        compressedData.reset();
        compressedData.write(red);
        compressedData.write(green);
        compressedData.write(blue);
        for (byte b : compressedData.toByteArray()) {
            System.out.print(b + ",");
        }
        System.out.println();

        compressedData.reset();
        compressedData.write((byte) red);
        compressedData.write((byte) green);
        compressedData.write((byte) blue);
        for (byte b : compressedData.toByteArray()) {
            System.out.print(b + ",");
        }
        System.out.println();

//        for (int i = 0; i < 255; i++) {
//            for (int j = 0; j < 255; j++) {
//                for (int k = 0; k < 255; k++) {
//                    Color color = new Color(i, j, k);
//                    int rgb = color.getRGB();
//                    if (rgb == 0) {
//                        System.out.println("rgb=" + rgb + ",r=" + color.getRed() + ",g=" + color.getGreen() + ",b=" + color.getBlue());
//                    }
//                }
//            }
//        }

    }

}
